package middleware

import (
	"com.lh.basic.service/lib/tools"
	"context"
	"encoding/json"
	"github.com/improbable-eng/grpc-web/go/grpcweb"
	"google.golang.org/grpc/metadata"
	"net/http"
)

type errorResponse struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
	Details string `json:"details,omitempty"`
}

// http条件过滤跨域方案
func FilterCors(h http.Handler, origin string) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if tools.AuthFilterHttpInterceptor(r) {
			w.Header().Set("Access-Control-Allow-Origin", origin)
			w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
			w.Header().Set("Access-Control-Allow-Headers", "Accept, x-grpc-web, x-user-agent, Content-Type, Content-Length, Accept-Encoding, Sid, Token, Uuid")
			w.Header().Set("Access-Control-Expose-Headers", "Content-Length")
			w.Header().Set("Access-Control-Allow-Credentials", "true")
			if r.Method == "OPTIONS" {
				w.WriteHeader(http.StatusNoContent)
				return
			}

			h.ServeHTTP(w, r)
		} else {
			w.Header().Set("Content-Type", "application/json")
			w.WriteHeader(200)
			_ = json.NewEncoder(w).Encode(errorResponse{
				Code:    401,
				Message: "not sid or token",
			})
			return
		}
	})
}

// http token验证与跨域解决方案
func Cors(h http.Handler, origin string) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if tools.AuthHttpInterceptor(r) {
			w.Header().Set("Access-Control-Allow-Origin", origin)
			w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
			w.Header().Set("Access-Control-Allow-Headers", "Accept, x-grpc-web, x-user-agent, Content-Type, Content-Length, Accept-Encoding, Sid, Token, Uuid")
			w.Header().Set("Access-Control-Expose-Headers", "Content-Length")
			w.Header().Set("Access-Control-Allow-Credentials", "true")
			if r.Method == "OPTIONS" {
				w.WriteHeader(http.StatusNoContent)
				return
			}
			h.ServeHTTP(w, r)
		} else {
			w.Header().Set("Content-Type", "application/json")
			w.WriteHeader(200)
			_ = json.NewEncoder(w).Encode(errorResponse{
				Code:    401,
				Message: "not sid or token",
			})
			return
		}
	})
}

// grpc-web跨域解决方案
func GrpcWebCors(h *grpcweb.WrappedGrpcServer, origin string) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Access-Control-Allow-Origin", origin)
		w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
		w.Header().Set("Access-Control-Allow-Headers", "Accept, x-grpc-web, x-user-agent, Content-Type, Content-Length, Accept-Encoding, Sid, Token, Uuid")
		w.Header().Set("Access-Control-Expose-Headers", "Content-Length")
		w.Header().Set("Access-Control-Allow-Credentials", "true")
		if h.IsGrpcWebRequest(r) || h.IsAcceptableGrpcCorsRequest(r) {
			h.ServeHTTP(w, r)
		} else {
			http.DefaultServeMux.ServeHTTP(w, r)
		}
	})
}

// gateway中重新设置自定义参数
func SetHeader(ctx context.Context, request *http.Request) metadata.MD {
	return metadata.Pairs(
		"sid", request.Header.Get("Sid"),
		"token", request.Header.Get("Token"),
		"uuid", request.Header.Get("Uuid"),
	)
}
